﻿using System;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x0200007A RID: 122
	public class HitReaction : OffsetModifier
	{
		// Token: 0x060004C9 RID: 1225 RVA: 0x00031984 File Offset: 0x0002FB84
		public override void OnModifyOffset()
		{
			foreach (HitReaction.HitPointEffector hitPointEffector in this.effectorHitPoints)
			{
				hitPointEffector.Apply(this.ik.solver, this.weight);
			}
			foreach (HitReaction.HitPointBone hitPointBone in this.boneHitPoints)
			{
				hitPointBone.Apply(this.ik.solver, this.weight);
			}
		}

		// Token: 0x060004CA RID: 1226 RVA: 0x00031A08 File Offset: 0x0002FC08
		public void Hit(Collider collider, Vector3 force, Vector3 point)
		{
			if (this.ik == null)
			{
				Debug.LogError("No IK assigned in HitReaction");
				return;
			}
			foreach (HitReaction.HitPointEffector hitPointEffector in this.effectorHitPoints)
			{
				if (hitPointEffector.collider == collider)
				{
					hitPointEffector.Hit(force, point);
				}
			}
			foreach (HitReaction.HitPointBone hitPointBone in this.boneHitPoints)
			{
				if (hitPointBone.collider == collider)
				{
					hitPointBone.Hit(force, point);
				}
			}
		}

		// Token: 0x0400034E RID: 846
		[Tooltip("Hit points for the FBBIK effectors")]
		public HitReaction.HitPointEffector[] effectorHitPoints;

		// Token: 0x0400034F RID: 847
		[Tooltip(" Hit points for bones without an effector, such as the head")]
		public HitReaction.HitPointBone[] boneHitPoints;

		// Token: 0x0200007B RID: 123
		[Serializable]
		public abstract class HitPoint
		{
			// Token: 0x1700006B RID: 107
			// (get) Token: 0x060004CC RID: 1228 RVA: 0x0000512D File Offset: 0x0000332D
			// (set) Token: 0x060004CD RID: 1229 RVA: 0x00005135 File Offset: 0x00003335
            public float crossFader { get; set; }

			// Token: 0x1700006C RID: 108
			// (get) Token: 0x060004CE RID: 1230 RVA: 0x0000513E File Offset: 0x0000333E
			// (set) Token: 0x060004CF RID: 1231 RVA: 0x00005146 File Offset: 0x00003346
            public float timer { get; set; }

			// Token: 0x1700006D RID: 109
			// (get) Token: 0x060004D0 RID: 1232 RVA: 0x0000514F File Offset: 0x0000334F
			// (set) Token: 0x060004D1 RID: 1233 RVA: 0x00005157 File Offset: 0x00003357
            public Vector3 force { get; set; }

			// Token: 0x1700006E RID: 110
			// (get) Token: 0x060004D2 RID: 1234 RVA: 0x00005160 File Offset: 0x00003360
			// (set) Token: 0x060004D3 RID: 1235 RVA: 0x00005168 File Offset: 0x00003368
            public Vector3 point { get; set; }

			// Token: 0x060004D4 RID: 1236 RVA: 0x00031AAC File Offset: 0x0002FCAC
			public void Hit(Vector3 force, Vector3 point)
			{
				if (this.length == 0f)
				{
					this.length = this.GetLength();
				}
				if (this.length <= 0f)
				{
					Debug.LogError("Hit Point WeightCurve length is zero.");
					return;
				}
				if (this.timer < 1f)
				{
					this.crossFader = 0f;
				}
				this.crossFadeSpeed = ((this.crossFadeTime <= 0f) ? 0f : (1f / this.crossFadeTime));
				this.CrossFadeStart();
				this.timer = 0f;
				this.force = force;
				this.point = point;
			}

			// Token: 0x060004D5 RID: 1237 RVA: 0x00031B58 File Offset: 0x0002FD58
			public void Apply(IKSolverFullBodyBiped solver, float weight)
			{
				float num = Time.time - this.lastTime;
				this.lastTime = Time.time;
				if (this.timer >= this.length)
				{
					return;
				}
				this.timer = Mathf.Clamp(this.timer + num, 0f, this.length);
				if (this.crossFadeSpeed > 0f)
				{
					this.crossFader = Mathf.Clamp(this.crossFader + num * this.crossFadeSpeed, 0f, 1f);
				}
				else
				{
					this.crossFader = 1f;
				}
				this.OnApply(solver, weight);
			}

			// Token: 0x060004D6 RID: 1238
			public abstract float GetLength();

			// Token: 0x060004D7 RID: 1239
			public abstract void CrossFadeStart();

			// Token: 0x060004D8 RID: 1240
			public abstract void OnApply(IKSolverFullBodyBiped solver, float weight);

			// Token: 0x04000350 RID: 848
			[Tooltip("Just for visual clarity, not used at all")]
			public string name;

			// Token: 0x04000351 RID: 849
			[Tooltip("Linking this hit point to a collider")]
			public Collider collider;

			// Token: 0x04000352 RID: 850
			[SerializeField]
			[Tooltip("Only used if this hit point gets hit when already processing another hit")]
			public float crossFadeTime = 0.1f;

			// Token: 0x04000353 RID: 851
			public float length;

			// Token: 0x04000354 RID: 852
			public float crossFadeSpeed;

			// Token: 0x04000355 RID: 853
			public float lastTime;
		}

		// Token: 0x0200007C RID: 124
		[Serializable]
		public class HitPointEffector : HitReaction.HitPoint
		{
			// Token: 0x060004DA RID: 1242 RVA: 0x00031BFC File Offset: 0x0002FDFC
			public override float GetLength()
			{
				float num = (this.offsetInForceDirection.keys.Length <= 0) ? 0f : this.offsetInForceDirection.keys[this.offsetInForceDirection.length - 1].time;
				float min = (this.offsetInUpDirection.keys.Length <= 0) ? 0f : this.offsetInUpDirection.keys[this.offsetInUpDirection.length - 1].time;
				return Mathf.Clamp(num, min, num);
			}

			// Token: 0x060004DB RID: 1243 RVA: 0x00031C94 File Offset: 0x0002FE94
			public override void CrossFadeStart()
			{
				foreach (HitReaction.HitPointEffector.EffectorLink effectorLink in this.effectorLinks)
				{
					effectorLink.CrossFadeStart();
				}
			}

			// Token: 0x060004DC RID: 1244 RVA: 0x00031CC8 File Offset: 0x0002FEC8
			public override void OnApply(IKSolverFullBodyBiped solver, float weight)
			{
				Vector3 a = solver.GetRoot().up * base.force.magnitude;
				Vector3 vector = this.offsetInForceDirection.Evaluate(base.timer) * base.force + this.offsetInUpDirection.Evaluate(base.timer) * a;
				vector *= weight;
				foreach (HitReaction.HitPointEffector.EffectorLink effectorLink in this.effectorLinks)
				{
					effectorLink.Apply(solver, vector, base.crossFader);
				}
			}

			// Token: 0x0400035A RID: 858
			[Tooltip("Offset magnitude in the direction of the hit force")]
			public AnimationCurve offsetInForceDirection;

			// Token: 0x0400035B RID: 859
			[Tooltip("Offset magnitude in the direction of character.up")]
			public AnimationCurve offsetInUpDirection;

			// Token: 0x0400035C RID: 860
			[Tooltip("Linking this offset to the FBBIK effectors")]
			public HitReaction.HitPointEffector.EffectorLink[] effectorLinks;

			// Token: 0x0200007D RID: 125
			[Serializable]
			public class EffectorLink
			{
				// Token: 0x060004DE RID: 1246 RVA: 0x00031D68 File Offset: 0x0002FF68
				public void Apply(IKSolverFullBodyBiped solver, Vector3 offset, float crossFader)
				{
					this.current = Vector3.Lerp(this.lastValue, offset * this.weight, crossFader);
					solver.GetEffector(this.effector).positionOffset += this.current;
				}

				// Token: 0x060004DF RID: 1247 RVA: 0x00005179 File Offset: 0x00003379
				public void CrossFadeStart()
				{
					this.lastValue = this.current;
				}

				// Token: 0x0400035D RID: 861
				[Tooltip("The FBBIK effector type")]
				public FullBodyBipedEffector effector;

				// Token: 0x0400035E RID: 862
				[Tooltip("The weight of this effector (could also be negative)")]
				public float weight;

				// Token: 0x0400035F RID: 863
				public Vector3 lastValue;

				// Token: 0x04000360 RID: 864
				public Vector3 current;
			}
		}

		// Token: 0x0200007E RID: 126
		[Serializable]
		public class HitPointBone : HitReaction.HitPoint
		{
			// Token: 0x060004E1 RID: 1249 RVA: 0x00031DB8 File Offset: 0x0002FFB8
			public override float GetLength()
			{
				return (this.aroundCenterOfMass.keys.Length <= 0) ? 0f : this.aroundCenterOfMass.keys[this.aroundCenterOfMass.length - 1].time;
			}

			// Token: 0x060004E2 RID: 1250 RVA: 0x00031E04 File Offset: 0x00030004
			public override void CrossFadeStart()
			{
				foreach (HitReaction.HitPointBone.BoneLink boneLink in this.boneLinks)
				{
					boneLink.CrossFadeStart();
				}
			}

			// Token: 0x060004E3 RID: 1251 RVA: 0x00031E38 File Offset: 0x00030038
			public override void OnApply(IKSolverFullBodyBiped solver, float weight)
			{
				if (this.rigidbody == null)
				{
					this.rigidbody = this.collider.GetComponent<Rigidbody>();
				}
				if (this.rigidbody != null)
				{
					Vector3 axis = Vector3.Cross(base.force, base.point - this.rigidbody.worldCenterOfMass);
					float angle = this.aroundCenterOfMass.Evaluate(base.timer) * weight;
					Quaternion offset = Quaternion.AngleAxis(angle, axis);
					foreach (HitReaction.HitPointBone.BoneLink boneLink in this.boneLinks)
					{
						boneLink.Apply(solver, offset, base.crossFader);
					}
				}
			}

			// Token: 0x04000361 RID: 865
			[Tooltip("The angle to rotate the bone around it's rigidbody's world center of mass")]
			public AnimationCurve aroundCenterOfMass;

			// Token: 0x04000362 RID: 866
			[Tooltip("Linking this hit point to bone(s)")]
			public HitReaction.HitPointBone.BoneLink[] boneLinks;

			// Token: 0x04000363 RID: 867
			public Rigidbody rigidbody;

			// Token: 0x0200007F RID: 127
			[Serializable]
			public class BoneLink
			{
				// Token: 0x060004E5 RID: 1253 RVA: 0x00031EEC File Offset: 0x000300EC
				public void Apply(IKSolverFullBodyBiped solver, Quaternion offset, float crossFader)
				{
					this.current = Quaternion.Lerp(this.lastValue, Quaternion.Lerp(Quaternion.identity, offset, this.weight), crossFader);
					this.bone.rotation = this.current * this.bone.rotation;
				}

				// Token: 0x060004E6 RID: 1254 RVA: 0x00005187 File Offset: 0x00003387
				public void CrossFadeStart()
				{
					this.lastValue = this.current;
				}

				// Token: 0x04000364 RID: 868
				[Tooltip("Reference to the bone that this hit point rotates")]
				public Transform bone;

				// Token: 0x04000365 RID: 869
				[Tooltip("Weight of rotating the bone")]
				[Range(0f, 1f)]
				public float weight;

				// Token: 0x04000366 RID: 870
				public Quaternion lastValue;

				// Token: 0x04000367 RID: 871
				public Quaternion current;
			}
		}
	}
}
